<template>
  <!-- 右键菜单容器，仅在 visible 为 true 时显示，位置由 top 和 left 控制 -->
  <div v-show="visible" class="context-menu" :style="{ top: top + 'px', left: left + 'px' }">
    <ul class="menu-list">
      <!-- 查看坐标菜单项 -->
      <li class="menu-item" @click="handleCommand('checkLocation')">
        <i class="el-icon-location"></i>
        <span>查看此处坐标</span>
      </li>

      <!-- 查看视角菜单项 -->
      <li class="menu-item" @click="handleCommand('checkView')">
        <i class="el-icon-view"></i>
        <span>查看当前视角</span>
      </li>

      <!-- 常用工具子菜单 -->
      <li class="menu-item submenu">
        <i class="el-icon-tools"></i>
        <span>常用工具</span>
        <i class="el-icon-arrow-right submenu-arrow"></i>
        <ul class="submenu-list">
          <li class="menu-item" @click="handleCommand('tool1')">工具1</li>
          <li class="menu-item" @click="handleCommand('tool2')">工具2</li>
        </ul>
      </li>

      <!-- 图上量算子菜单 -->
      <li class="menu-item submenu">
        <i class="el-icon-data-analysis"></i>
        <span>图上量算</span>
        <i class="el-icon-arrow-right submenu-arrow"></i>
        <ul class="submenu-list">
          <li class="menu-item" @click="handleCommand('measure1')">距离量算</li>
          <li class="menu-item" @click="handleCommand('measure2')">面积量算</li>
        </ul>
      </li>

      <!-- 图上标记子菜单 -->
      <li class="menu-item submenu">
        <i class="el-icon-edit"></i>
        <span>图上标记</span>
        <i class="el-icon-arrow-right submenu-arrow"></i>
        <ul class="submenu-list">
          <li class="menu-item" @click="handleCommand('mark1')">点标记</li>
          <li class="menu-item" @click="handleCommand('mark2')">线标记</li>
          <li class="menu-item" @click="handleCommand('mark3')">面标记</li>
        </ul>
      </li>

      <!-- 视角切换子菜单 -->
      <li class="menu-item submenu">
        <i class="el-icon-camera"></i>
        <span>视角切换</span>
        <i class="el-icon-arrow-right submenu-arrow"></i>
        <ul class="submenu-list">
          <li class="menu-item" @click="handleCommand('view1')">视角1</li>
          <li class="menu-item" @click="handleCommand('view2')">视角2</li>
        </ul>
      </li>

      <!-- 特效效果子菜单 -->
      <li class="menu-item submenu">
        <i class="el-icon-magic-stick"></i>
        <span>特效效果</span>
        <i class="el-icon-arrow-right submenu-arrow"></i>
        <ul class="submenu-list">
          <li class="menu-item" @click="handleCommand('effect1')">雨天</li>
          <li class="menu-item" @click="handleCommand('effect2')">雪天</li>
          <li class="menu-item" @click="handleCommand('effect3')">雾天</li>
        </ul>
      </li>

      <!-- 地形服务子菜单 -->
      <li class="menu-item submenu">
        <i class="el-icon-s-platform"></i>
        <span>地形服务</span>
        <i class="el-icon-arrow-right submenu-arrow"></i>
        <ul class="submenu-list">
          <li class="menu-item" @click="handleCommand('terrain1')">地形1</li>
          <li class="menu-item" @click="handleCommand('terrain2')">地形2</li>
        </ul>
      </li>

      <!-- 场景设置子菜单 -->
      <li class="menu-item submenu">
        <i class="el-icon-setting"></i>
        <span>场景设置</span>
        <i class="el-icon-arrow-right submenu-arrow"></i>
        <ul class="submenu-list">
          <li class="menu-item" @click="handleCommand('setting1')">设置1</li>
          <li class="menu-item" @click="handleCommand('setting2')">设置2</li>
        </ul>
      </li>
    </ul>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'

// 接收父组件传递的地球对象
const props = defineProps({
  objm: Object, // 地球对象，用于获取地球相关信息和操作
})

// 定义组件向外发射的事件
const emit = defineEmits(['command'])

// 控制菜单显示状态
const visible = ref(false)
// 菜单位置坐标
const top = ref(0)
const left = ref(0)
// 存储最后一次右键点击的事件对象，用于后续获取点击位置
const lastEvent = ref(null)

/**
 * 显示右键菜单
 * @param {MouseEvent} e - 鼠标右键事件对象
 */
const show = (e) => {
  // 阻止默认的浏览器右键菜单
  e.preventDefault()

  // 显示自定义菜单
  visible.value = true

  // 设置菜单位置为鼠标点击位置
  top.value = e.clientY
  left.value = e.clientX

  // 保存事件对象，用于后续处理
  lastEvent.value = e

  // 防止菜单超出视窗边界的处理
  // 使用 setTimeout 确保在 DOM 更新后再获取菜单尺寸
  setTimeout(() => {
    const menu = document.querySelector('.context-menu')
    if (!menu) return
    //getBoundingClientRect返回一个 DOMRect 对象，其提供了元素的大小及其相对于视口的位置。
    const menuRect = menu.getBoundingClientRect()
    const windowWidth = window.innerWidth // window.innerWidth 返回视口的宽度
    const windowHeight = window.innerHeight

    // 如果菜单右侧超出窗口，则将菜单左移
    if (menuRect.right > windowWidth) {
      left.value = windowWidth - menuRect.width
    }

    // 如果菜单底部超出窗口，则将菜单上移
    if (menuRect.bottom > windowHeight) {
      top.value = windowHeight - menuRect.height
    }
  }, 0)
}

/**
 * 隐藏右键菜单
 */
const hide = () => {
  visible.value = false
}

/**
 * 处理菜单项点击事件
 * @param {string} command - 菜单命令标识
 */
const handleCommand = (command) => {
  // 向父组件发送命令和事件对象
  emit('command', { command, event: lastEvent.value })
  // 执行命令后隐藏菜单
  hide()
}

/**
 * 处理点击菜单外部区域的事件
 * @param {MouseEvent} e - 鼠标点击事件对象
 */
const handleClickOutside = (e) => {
  // 如果菜单可见且点击位置不在菜单内，则隐藏菜单
  if (visible.value && !e.target.closest('.context-menu')) {
    hide()
  }
}

// 组件挂载时添加全局事件监听
onMounted(() => {
  // 监听全局点击事件，用于关闭菜单
  document.addEventListener('click', handleClickOutside)

  // 监听全局右键事件，阻止地球区域的默认右键菜单     //通常在鼠标点击右键或者按下键盘上的菜单键时被触发
  document.addEventListener('contextmenu', (e) => {
    if (e.target.closest('.earth')) {
      e.preventDefault()
    }
  })
})

// 组件卸载时移除全局事件监听，防止内存泄漏
onUnmounted(() => {
  document.removeEventListener('click', handleClickOutside)
  document.removeEventListener('contextmenu', (e) => {
    if (e.target.closest('.earth')) {
      e.preventDefault()
    }
  })
})

// 向父组件暴露方法
defineExpose({
  show, // 显示菜单方法
  hide, // 隐藏菜单方法
})
</script>

<style lang="scss" scoped>
.context-menu {
  position: fixed; /* 固定定位，相对于视窗 */
  z-index: 1000; /* 确保菜单显示在其他元素上方 */
  background: #1e2a3a; /* 深色背景，适合地球应用 */
  border-radius: 4px; /* 圆角边框 */
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3); /* 阴影效果 */
  padding: 5px 0;
  min-width: 150px;

  /* 菜单列表样式 */
  .menu-list {
    margin: 0;
    padding: 0;
    list-style: none;

    /* 菜单项样式 */
    .menu-item {
      padding: 8px 16px;
      cursor: pointer;
      color: #fff;
      font-size: 14px;
      display: flex;
      align-items: center;
      position: relative;

      /* 图标样式 */
      i {
        margin-right: 8px;
        font-size: 16px;
      }

      /* 鼠标悬停效果 */
      &:hover {
        background-color: #409eff;
      }

      /* 子菜单样式 */
      &.submenu {
        /* 子菜单箭头图标 */
        .submenu-arrow {
          position: absolute;
          right: 10px;
          margin-right: 0;
        }

        /* 子菜单列表 */
        .submenu-list {
          display: none; /* 默认隐藏 */
          position: absolute;
          left: 100%; /* 在父菜单右侧显示 */
          top: 0;
          background: #1e2a3a;
          border-radius: 4px;
          box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.3);
          padding: 0;
          min-width: 120px;
          list-style: none;
        }

        /* 鼠标悬停时显示子菜单 */
        &:hover {
          .submenu-list {
            display: block;
          }
        }
      }
    }
  }
}
</style>
